home *** CD-ROM | disk | FTP | other *** search
- *****Listing 4*****
-
- #include <errno.h>
- #include <limits.h>
- #include <stdio.h>
- #include <string.h>
- #define PATHDLM ('/') /* path name delimiter */
- #include "rwsem.h"
-
- /* function declarations */
- int getcnt(char *file, int *cntp);
- int putcnt(char *file, int cnt);
-
- /* read/write semaphore set table definition */
- static rwsset_t rwst[RWSOPEN_MAX];
-
- /* rwslock: read/write semaphore lock */
- int rwslock(rwsset_t *rwsp, int rwsno, int ltype)
- {
- int wsem = 0; /* write semaphore */
- int rsem = 0; /* read semaphore */
- int rc = 0; /* readcount */
- char rcpath[PATH_MAX + 1]; /* readcount file path name */
-
- /* identify write and read semaphores and read-count file */
- wsem = rwsno * 2;
- rsem = wsem + 1;
- sprintf(rcpath, "%s%cr%d", rwsp->rwsdir, (int)PATHDLM, rwsno);
-
- switch (ltype) {
- case RWS_UNLCK: /* unlock */
- switch (rwsp->lockheld[rwsno]) {
- case RWS_UNLCK: /* unlock */
- break; /* case RWS_UNLCK: */
- case RWS_RDLCK: /* read lock */
- if (semlower(rwsp->ssp, rsem) == -1) { /* allocate readcount */
- return -1;
- }
- getcnt(rcpath, &rc); /* get readcount */
- rc--; /* decrement readcount */
- if (rc == 0) { /* if no other readers, */
- if (semraise(rwsp->ssp, wsem) == -1) { /* free resource */
- semraise(rwsp->ssp, rsem);
- return -1;
- }
- }
- putcnt(rcpath, rc); /* store new readcount */
- if (semraise(rwsp->ssp, rsem) == -1) { /* free readcount */
- return -1;
- }
- break; /* case RWS_RDLCK: */
- case RWS_WRLCK: /* write lock */
- if (semraise(rwsp->ssp, wsem) == -1) {
- return -1;
- }
- break; /* case RWS_WRLCK: */
- default:
- errno = RWSPANIC;
- return -1;
- break; /* default: */
- };
- break; /* case RWS_UNLCK: */
- case RWS_RDLCK: /* read lock */
- if (rwsp->lockheld[rwsno] == RWS_RDLCK) {
- errno = 0;
- return 0;
- }
- if (semlower(rwsp->ssp, rsem) == -1) { /* allocate readcount */
- return -1;
- }
- getcnt(rcpath, &rc); /* get readcount */
- rc++; /* increment readcount */
- if (rc == 1) { /* if no other readers, */
- if (semlower(rwsp->ssp, wsem) == -1) { /* allocate resource */
- semraise(rwsp->ssp, rsem);
- return -1;
- }
- }
- putcnt(rcpath, rc); /* store new readcount */
- if (semraise(rwsp->ssp, rsem) == -1) { /* free readcount */
- if (rc == 1) semraise(rwsp->ssp, wsem);
- return -1;
- }
- break; /* case RWS_RDLCK: */
- case RWS_WRLCK: /* write lock */
- if (semlower(rwsp->ssp, wsem) == -1) { /* allocate resource */
- return -1;
- }
- break; /* case RWS_WRLCK: */
- default:
- errno = EINVAL;
- return -1;
- break; /* default: */
- };
-
- /* save type of lock held */
- rwsp->lockheld[rwsno] = ltype;
-
- errno = 0;
- return 0;
- }
-
-